﻿<%
'''Oracle数据库模型驱动类
Class AshapoModelDriverOracle
	
	
	'当前数据库对象
	Private s_db
	
	'当前表模型(为空表示数据库全局)
	Private s_table
	
	'当前表一级前缀
	Private s_prefix
	
	'当前表二级前缀
	Private s_prefix2
	
	'当前数据表别名(为空表示不需要)
	Private s_alias
	
	'top值(为空表示不需要使用TOP)
	Private s_top
	
	'field值(要查询的字段)
	Private s_field
	
	'join值(要进行JOIN的完整语句)
	Private s_join
	
	'union值(含UNION 和 UNION ALL)
	Private s_union
	
	'where(当前条件定义)
	Private s_where
	
	'order(当前排序定义)
	Private s_order
	
	'当前的组装SQL语句
	Private s_sql
	
	Private s_cfg
	
	'''构造
	Private Sub Class_Initialize()
		Set s_cfg = New AshapoConfig
		Set s_db = New AshapoDatabase
		s_table = ""
		s_prefix = ""
		s_alias = ""
		s_top = ""
		s_field = "*"
		s_join = ""
		s_union = ""
		s_where = ""
		s_order = ""
	End Sub
	
	'''析构
	Private Sub Class_Terminate()
		Set s_db = Nothing
		Set s_cfg = Nothing
	End Sub

	'''初始化
	'p_server:Oracle服务器
	'p_port:Oracle端口
	'p_database:指定数据库
	'p_user:账户
	'p_pwd:密码
	Public Sub Init(Byval p_server, Byval p_port, Byval p_database, Byval p_user, Byval p_pwd)
		Dim t_provider : t_provider = "Provider=msdaora;Data Source=" & p_server & ";User Id=" & p_user & ";Password=" & p_pwd & ";"
		s_db.Init( t_provider )
	End Sub
	
	'''获取当前的数据库原型
	Public Property Get DataBase()
		Set DataBase = s_db
	End Property

	
	'''设置当前表,默认使用
	'p_t:不含各类前缀的表名
	Public Function [Table](Byval p_t)
		s_table = p_t
		Set [Table] = Me
	End Function
	
	'''设置当前表的真实名称
	'p_t:表完整名称
	Public Function RealTable(Byval p_t)
		s_table = p_t
		s_prefix = ""
		s_prefix2 = ""
		Set RealTable = Me
	End Function
	
	'''设置表的一级前缀
	Public Function Prefix(Byval p_s)
		s_prefix = p_s
		Set Prefix = Me
	End Function
	
	'''设置表的二级前缀
	Public Function SecondPrefix(Byval p_s)
		s_prefix2 = p_s
		Set SecondPrefix = Me
	End Function
	
	'''给当前数据表定义别名
	Public Function [Alias](Byval p_s)
		If p_s <> "" Then
			s_alias = " AS " & p_s
		End If
		Set [Alias] = Me
	End Function
	
	'''查询前几个
	Public Function Top(Byval p_i)
		If p_i <> "" Then
			s_top = "TOP " & p_i & " "
		End If
		Set Top = Me
	End Function
	
	'''指定查询字段
	Public Function Field(Byval p_s)
		If p_s <> "" Then
			s_field = p_s
		End If
		Set [Field] = Me
	End Function
	
	'''查询SQL组装 join
	Public Function [Join](Byval p_s)
		s_join = s_join & p_s
		Set [Join] = Me
	End Function
	
	'''指定查询条件
	Public Function Where(Byval p_s)
		s_where = p_s
		Set Where = Me
	End Function
	
	'''对结果排序
	Public Function [Order](Byval p_s)
		If p_s <> "" Then
			s_order = " ORDER BY " & p_s
		End If
		Set [Order] = Me
	End Function
	
	'''UNION组装
	Public Function Union(Byval p_s)
		s_union = s_union & " UNION " & p_s
		Set Union = Me
	End Function
	
	'''Union All组装
	Public Function UnionAll(Byval p_s)
		s_union = s_union & " UNION ALL " & p_s
		Set UnionAll = Me
	End Function
	
	'''查询数据集,返回结果数组
	Public Function [Select]()
		If s_where = "" Then
			s_sql = "SELECT " & s_top & s_field & " FROM " & s_prefix & s_prefix2 & s_table & s_alias & s_join & s_union & s_order
		Else
			s_sql = "SELECT " & s_top & s_field & " FROM " & s_prefix & s_prefix2 & s_table & s_alias & s_join & s_union &" WHERE " & s_where & s_order
		End If
		
		'返回数组
		Dim t_rs : Set t_rs = s_db.Query(s_sql)
		Dim t_arr
		ReDim t_arr(t_rs.RecordCount - 1)
		Dim t_x, t_i : t_i = 0
		While Not t_rs.Eof
			Set t_arr( t_i ) = Server.CreateObject( s_cfg.Environment("Scripting.Dictionary") )
			For Each t_x In t_rs.Fields
				t_arr( t_i )( t_x.Name ) = t_x.Value
			Next
			t_i = t_i + 1
			t_rs.MoveNext()
		Wend
		s_db.Close(t_rs)
		[Select] = t_arr
	End Function
	
	'''返回原生记录集
	Public Function [Recordset]()
		If s_where = "" Then
			s_sql = "SELECT " & s_top & s_field & " FROM " & s_prefix & s_prefix2 & s_table & s_alias & s_join & s_union & s_order
		Else
			s_sql = "SELECT " & s_top & s_field & " FROM " & s_prefix & s_prefix2 & s_table & s_alias & s_join & s_union &" WHERE " & s_where & s_order
		End If
		Set [Recordset] = s_db.Query(s_sql)
	End Function
	
	'''获取记录个数
	Public Function [Count]()
		Dim t_r : Set t_r = [Select]()
		[Count] = t_r.RecordCount
		s_db.Close(t_r)
	End Function
	
	'''分页查询
	'''todo 待改写
	'p_p:每页数量
	'p_i:指定页码
	Public Function [Page](Byval p_p, Byval p_i)
		Dim t_r : Set t_r = [Select]()
		t_r.PageSize = p_p
		Dim t_c : t_c = t_r.PageCount
		If p_i > t_c Then
			p_i = t_c
		End If
		t_r.AbsolutePage = p_i
		Set [Page] = t_r
	End Function
	
	'''查询单条数据
	Public Function [Find]()
		s_top = "1"
		Set [Find] = [Select]()
	End Function
	
	
	Public Function GetLastSQL()
	End Function
	
	
	
	'''添加一条记录
	Public Function [Add](Byval p_d)
		Set [Add] = s_db.AddRecord(s_prefix & s_prefix2 & s_table, p_d)
	End Function
	
	'''更新记录
	Public Function [Update](Byval p_d)
		[Update] = s_db.UpdateRecord(s_prefix & s_prefix2 & s_table, s_where, p_d)
	End Function
	
	'''删除记录
	Public Function [Delete]()
		[Delete] = s_db.DeleteRecord(s_prefix & s_prefix2 & s_table, s_where)
	End Function
	
	
	'''添加一条记录，成功返回该记录，失败返回Nothing
	Public Function AddRecord(Byval p_t, Byval p_d)
		On Error Resume Next
		Dim t_r : Set t_r = Server.CreateObject("Adodb.Recordset")
		Dim t_q : t_q = "SELECT TOP 1 * FROM [" & p_t & "]"
		Call t_r.Open(t_q, s_conn, 1, 3)
		t_r.AddNew()
		For Each t_key In p_d
			t_r(t_key) = p_d(t_key)
		Next
		t_r.Update()
		Set AddRecord = t_r
		If Err.number <> 0 Then
			Dim t_log : t_log = dbLog_("插入记录时发生错误!")
			Console.Warn(t_log)
			Err.Clear()
			Set AddRecord = Nothing
		End If
		Console.DbQueryTimes = Console.DbQueryTimes + 1
	End Function
	
	'''根据指定条件更新记录
	'p_t:表名
	'p_d:更新的字段及值对
	'p_w:条件(字符串)
	Public Function UpdateRecord(Byval p_t, Byval p_d, Byval p_w)
		'判断各参数类型
		Dim t_q,t_a,t_k,t_u : t_u = ""
		For Each t_k In p_d
			t_a = ""
			Select Case TypeName(p_d(t_k))
			Case "Byte", "Integer", "Long", "Single", "Double", "Currency", "Decimal"
				'数字型
				t_a = t_k & " = " & CStr(p_d(t_k))
			Case "Date"
				'时间型
				t_a = t_k & " = #" & CStr(p_d(t_k)) & "#"
			Case "String"
				'字符串
				t_a = t_k & " = '" & CStr(Replace(p_d(t_k),"'","''")) & "'"
			Case "Boolean"
				t_a = t_k & " = " & CStr(p_d(t_k))
			Case "Null"
				t_a = t_k & " = NULL"
			Case Else
				Console.Error("更新记录时发生错误，不允许的参数类型" & TypeName(p_d(t_k)))
			End Select
			If t_u = "" Then
				t_u = t_a
			Else
				t_u = t_u & ", " & t_a
			End If
		Next
		If p_w = "" Then
			t_q = "UPDATE [" & p_t & "] SET " & t_u
		Else
			t_q = "UPDATE [" & p_t & "] SET " & t_u & " WHERE " & p_w
		End If
		Console.SQL(t_q)
		UpdateRecord = doExecute_(t_q)
	End Function
	
	'''根据指定条件删除记录,成功返回影响个数，失败返回False
	'p_t:表名
	'p_w:条件(条件字符串)
	Public Function DeleteRecord(Byval p_t,Byval p_w)
		Dim t_q
		If p_w = "" Then
			t_q = "DELETE FROM [" & p_t & "]"
		Else
			t_q = "DELETE FROM [" & p_t & "] WHERE " & p_w
		End If
		Console.SQL(t_q)
		DeleteRecord = doExecute_(t_q)
	End Function
		
End Class
%>